package com.pay.game.central.web.controller;


import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.fasterxml.uuid.Generators;
import com.github.pagehelper.Page;
import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import com.pay.game.central.common.Result;
import com.pay.game.central.common.ResultGenerator;
import com.pay.game.central.security.annotaion.UserLoginToken;
import com.pay.game.central.utils.RequestUtils;
import com.pay.game.central.utils.bean.MyHeader;
import com.pay.game.central.web.bean.GroupOrderId;
import com.pay.game.central.web.bean.Order;
import com.pay.game.central.web.bean.OrderStatistic;
import com.pay.game.central.web.bean.PayStatistic;
import com.pay.game.central.web.mapper.TestMapper;
import com.pay.game.central.web.service.*;
import org.apache.hc.client5.http.classic.methods.HttpPost;
import org.apache.hc.client5.http.entity.UrlEncodedFormEntity;
import org.apache.hc.client5.http.impl.classic.CloseableHttpClient;
import org.apache.hc.client5.http.impl.classic.CloseableHttpResponse;
import org.apache.hc.client5.http.impl.classic.HttpClients;
import org.apache.hc.core5.http.HttpEntity;
import org.apache.hc.core5.http.NameValuePair;
import org.apache.hc.core5.http.ParseException;
import org.apache.hc.core5.http.io.entity.EntityUtils;
import org.apache.hc.core5.http.message.BasicNameValuePair;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.util.StringUtils;
import org.springframework.web.bind.annotation.*;

import java.io.IOException;
import java.math.BigDecimal;
import java.sql.Date;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

@RestController
@RequestMapping("order")
public class OrderController {

    @Value("${serverip}")
    private String serverip;

    @Autowired
    private GoodsService goodsService;
    @Autowired
    private StoreService storeService;
    @Autowired
    private OrderService orderService;
    @Autowired
    private DirectoryService directoryService;
    @Autowired
    private StatisticService statisticService;

    @Autowired
    private HistoryOrderService historyOrderService;

    @Autowired
    private TestService testService;

    /**
     * 获取商品信息
     * /order
     * GET
     * @param price 价格（分）
     * @return { goods_id: 商品ID,price: 价格(分),group_id: groupId,sku_id: skuId }
     */
    @GetMapping
//    @UserLoginToken
    @ResponseBody
    Result<Map<String,Object>> getOrder(int price, String userId, int type){
        if (StringUtils.isEmpty(userId)){
            return ResultGenerator.genFailResult("userId不能为空");
        }
//        List<Map<String,Object>> goodsInfos = goodsService.getOrderGoodsByPrice(price);
        Map<String,Integer> lockOrderSize = historyOrderService.lockOrderSize();
        //价格区间
        int runRangeLt = directoryService.getRunRangeLt();

        List<Map<String,Object>> goodsInfos = null;
        //type ==0 表示拼单
        if(type==0){
            goodsInfos = goodsService.getOrderGoodsPd(price, runRangeLt, userId);
        }else {
            goodsInfos =  goodsService.getOrderGoods(price, runRangeLt, userId);
        }
        int timeInterval = directoryService.getGoodsTimeInterval();
        int threshold = directoryService.getThreshold();
        Map<String,Object> result_has_score = null;
        List<Map<String,Object>> result_no_score = new ArrayList<>();
        int currentTime = (int) (System.currentTimeMillis() / 1000);
        List<String> ids = goodsInfos.stream().map(item -> item.get("store_id").toString()).collect(Collectors.toList());
        List<Map<String, Object>> doneTimes = null;
        if (!ids.isEmpty()) doneTimes = goodsService.getStoreDonSize(ids);
        for (Map<String,Object> item: goodsInfos) {
            int payTime = (int) item.get("pay_time");
            int orderLimit = (int) item.get("order_limit");
            int score = (int) item.get("score");
            int usedScore = (int) item.get("used_score");
//            int doneSize = (int) item.get("done_size");
            int doneSize = orderLimit;
            for (Map<String, Object> map: doneTimes) {
                if (map.get("id").toString().equals(item.get("store_id").toString())){
                    doneSize = ((BigDecimal) map.get("done_times")).intValue();
                }
            }
            //是否超出时间钟限制
            boolean timeIntervalPass = currentTime - payTime >= timeInterval;
            Integer not_pay_size = lockOrderSize.get(item.get("store_id").toString());
            if (not_pay_size == null) not_pay_size = 0;
            //商店是否还可以下单
            boolean orderLimitPass = doneSize +  not_pay_size < orderLimit;
//            orderLimit +
            if (timeIntervalPass && orderLimitPass) {
                //找出跑分没上限的商品
                if (score >= usedScore + price){
                    result_has_score = item;
                    break;
                }
                if (score * (100 + threshold) / 100 >= usedScore + price) {
                    result_no_score.add(item);
                }

            }
        }
        if (null == result_has_score && result_no_score.isEmpty()) {
            return ResultGenerator.genFailResult("未找到合适商品");
        }else {
            Map<String,Object> result = result_has_score;
            if (null == result) result = result_no_score.get(0);
            String goodsId = (String) result.get("goods_id");
            //记录轮询次数
            goodsService.increaseLoopTime(goodsId);
            //记录生成订时间戳
            goodsService.setOrderTime(goodsId, System.currentTimeMillis());
            //记录下单统计信息到统计表
            OrderStatistic orderStatistic = new OrderStatistic();
            orderStatistic.setDate(new Date(System.currentTimeMillis()));
            orderStatistic.setDatetime((int) (System.currentTimeMillis() / 1000));
            orderStatistic.setGoods_id(goodsId);
            orderStatistic.setUser_id(result.get("user_id").toString());
            orderStatistic.setStore_id(result.get("store_id").toString());
            statisticService.insertOrderStatistic(orderStatistic);
            String tag = Generators.timeBasedGenerator().generate().toString();
            result.put("tag", tag);
            historyOrderService.putNewOrder(result.get("store_id").toString(), tag, (int) (System.currentTimeMillis()/1000));
            result.remove("store_id");
            result.remove("score");
            result.remove("order_time");
            result.remove("used_score");
            result.remove("order_limit");
            result.remove("pay_time");
            result.remove("user_id");
            //拼单时要获取group_order_id
            if (type==0){
                List<GroupOrderId> groupOrderIds = goodsService.getGroupOrderId(goodsId);
                if (null == groupOrderIds || groupOrderIds.isEmpty()){
                    result.put("group_order_id", null);
                } else {
                    result.put("group_order_id", groupOrderIds.get(0).getId());
                }
            }

            return ResultGenerator.genSuccessResult(result);
        }
    }

    /**
     * 付款信息回调
     * /order
     * POST
     * requestBody: {
     *                  id: 订单ID,
     *                  pddOrderId: 拼多多平台生成的订单号,
     *                  goodsId: 商品id,
     *                  payStatus: 支付状态 (0未支付,1成功支付,2客户放弃,3支付超时),
     *                  status: 订单状态(0未生成,1未支付,2未发货,3未签收,4已完成)
     *              }
     */
    @PostMapping
    @ResponseBody
    Result<String> updateOrder(@RequestBody String body){
        JSONObject jsonObject = JSON.parseObject(body);
        String id = jsonObject.getString("pddOrderId");
        //检查是否已经上传
        Order oldOrder = orderService.findPddOrderById(id);
        if (oldOrder != null) return ResultGenerator.genFailResult("重复pddOrderId");

        String groupOrderId = jsonObject.getString("group_order_id");
        String goodsId = jsonObject.getString("goodsId");
        String tag = jsonObject.getString("tag");
        String payType = jsonObject.getString("payType");
        String fromPlatform = jsonObject.getString("fromPlatform");
        int ctime = jsonObject.getInteger("ctime");
        int price = jsonObject.getIntValue("total");
        if (!StringUtils.isEmpty(groupOrderId)){
            goodsService.insertOrIncreaseGroupOrderId(groupOrderId, goodsId);
        }
        Map<String, Object> map = goodsService.getGoodsDetailInfo(goodsId);
        Order order = new Order();
        order.setGoods_id(goodsId);
        order.setId(id);
        order.setGoods_name((String) map.get("goods_name"));
        order.setUser_id((String) map.get("user_id"));
        order.setUser_name((String) map.get("user_name"));
        order.setStore_id((String) map.get("store_id"));
        order.setStore_name((String) map.get("store_name"));
        order.setPay_type(payType.equals("alipay") ? Order.PAY_TYPE_ALIPAY : Order.PAY_TYPE_WECHAT);
        order.setPay_platform(fromPlatform.equals("pdd") ? Order.PAY_PLATFORM_PDD : Order.PAY_PLATFORM_QRCODE);
        order.setPay_time(ctime);
        order.setPrice(price);
        order.setSettlement_id((Long) map.get("settlement_id"));
        orderService.insertPddOrder(order);
        //设置店铺跑分数
        storeService.addUsedScore(goodsId, price);
        //增加下单数统计
        storeService.increaseOrderLimit(goodsId);
        //移除缓存中订单
        historyOrderService.removeOldOrder(tag);
        goodsService.increaseDoneTimeAndSetPayTime(goodsId, ctime);
//        goodsService.setGroupOrderId(goodsId, groupOrderId);
        //记录支付统计信息到统计表
        PayStatistic payStatistic = new PayStatistic();
        payStatistic.setDate(new Date(System.currentTimeMillis()));
        payStatistic.setDatetime((int) (System.currentTimeMillis() / 1000));
        payStatistic.setGoods_id(goodsId);
        payStatistic.setUser_id((String) map.get("user_id"));
        payStatistic.setStore_id((String) map.get("store_id"));
        statisticService.insertPayStatistic(payStatistic);
        return ResultGenerator.genSuccessResult("状态更新成功");
    }

    @PostMapping("/sign")
    @ResponseBody
    Result<String> signOrder(@RequestBody  String body){
        JSONObject jsonObject = JSON.parseObject(body);
        String id = jsonObject.getString("pddOrderId");
        int signTime = jsonObject.getIntValue("sign_time");
        Order order = new Order();
        order.setId(id);
        order.setSign_time(signTime);
        orderService.updateSignTime(order);
        return ResultGenerator.genSuccessResult("状态更新成功");
    }

    @UserLoginToken
    @PostMapping("/signin/list")
    @ResponseBody
    Result<String> signinList(@RequestBody  String body){
        JSONObject jsonObject = JSON.parseObject(body);
        List<String> ids = jsonObject.getJSONArray("ids").stream().map(Object::toString).collect(Collectors.toList());
        try (CloseableHttpClient httpclient = HttpClients.createDefault()) {
            HttpPost httpPost = new HttpPost("http://" + serverip + "/api/order/signForOrder");
            List<NameValuePair> nvps = new ArrayList<>();
            StringBuilder sb = new StringBuilder();
            sb.append("{");
            ids.forEach(id -> sb.append("\""+ id +"\","));
            sb.deleteCharAt(sb.lastIndexOf(","));
            sb.append("}");
            nvps.add(new BasicNameValuePair("order_sn", sb.toString()));
            httpPost.setEntity(new UrlEncodedFormEntity(nvps));
            try (CloseableHttpResponse response2 = httpclient.execute(httpPost)) {
                HttpEntity entity2 = response2.getEntity();
                JSONObject rs = JSON.parseObject(EntityUtils.toString(entity2));
                if (rs.getIntValue("code") == 0) {
                    return ResultGenerator.genSuccessResult("签收成功");
                }
                return ResultGenerator.genFailResult("签收失败");
            }
        } catch (IOException | ParseException e) {
            e.printStackTrace();
            return ResultGenerator.genFailResult("签收失败: " + e.toString());
        }
    }

    @UserLoginToken
    @GetMapping("/list")
    @ResponseBody
    Result<PageInfo<Order>> list(@RequestHeader Map<String, String> headers,
                                 @RequestParam(defaultValue = "1") int page,
                                 @RequestParam(defaultValue = "20") int limit,
                                 String id, int price, String startTime,String endTime,
                                 String storeId, String storeName) {
        MyHeader myHeader = RequestUtils.parseHeader(headers);
        PageHelper.startPage(page,limit);
        Page<Order> result = orderService.list(myHeader.isAdmin(), myHeader.getUserId(),id, price, startTime, endTime, storeId, storeName);
        return ResultGenerator.genSuccessResult(new PageInfo(result));
    }

    @UserLoginToken
    @GetMapping("/listHistorySign")
    @ResponseBody
    Result<PageInfo<Map<String, Object>>> listHistorySign(
            @RequestHeader Map<String, String> headers,
            @RequestParam(defaultValue = "1") int page,
            @RequestParam(defaultValue = "10") int limit,
            @RequestParam(defaultValue = "1") int needSign){
        MyHeader myHeader = RequestUtils.parseHeader(headers);
        PageHelper.startPage(page, limit);
        return ResultGenerator.genSuccessResult(new PageInfo<>(orderService.listSignHistory(myHeader.isAdmin(), myHeader.getUserId(), needSign)));
    }


    @UserLoginToken
    @GetMapping("/listNeedSign")
    @ResponseBody
    Result<List<Map<String, Object>>> listNeedSign(@RequestHeader Map<String, String> headers, String storeName, String storeId){
        MyHeader myHeader = RequestUtils.parseHeader(headers);
        return ResultGenerator.genSuccessResult(orderService.listNeedSign(myHeader.isAdmin(), myHeader.getUserId(), storeId, storeName));
    }



}
